package top.lushi78778.iot.mqtt.web.api.v1;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.onsmqtt20200420.models.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.lushi78778.iot.mqtt.configurer.MqttConfigurer;
import top.lushi78778.iot.mqtt.core.MqttClient;
import top.lushi78778.iot.mqtt.core.Result;
import top.lushi78778.iot.mqtt.core.ResultGenerator;

/**
 * @ClassName TraceMessage
 * @Description 轨迹查询接口
 * @Author lushi
 * @Date 2021/7/19 19:51
 */
@RestController
@RequestMapping("/api/trace")
public class TraceMessage {

    /**
     * 调用QueryMqttTraceDevice分页查询微消息队列MQTT版客户端的设备轨迹
     *
     * @param Reverse 返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之
     * @param ClientId 需要查询轨迹信息的设备的Client ID
     * @param BeginTime 查询范围的起始时间戳
     * @param EndTime 查询范围的终止时间戳
     * @param CurrentPage 当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空
     * @param PageSize 分页查询，每页最多显示的消息数量，最小1条，最多100条
     * @return RequestId 公共参数 Total 信息总数 CurrentPage 当前页 PageSize 每页数量 DeviceInfoList 信息明细。
     * Action 设备动作。取值说明如下：
     *   connect：客户端请求与服务端连接。
     *   close：TCP连接断开。
     *   disconnect：客户端请求与服务端断开连接。
     * ActionCode 设备动作的返回码。取值说明如下：
     *   mqtt.trace.action.connect：设备动作为connect时返回该参数值。
     *   mqtt.trace.action.close：设备动作为close时返回该参数值。
     *   mqtt.trace.action.disconnect：设备动作为disconnect时返回该参数值。
     * ActionInfo 设备动作的描述信息。取值说明如下：
     *   accept：服务端接收客户端发起的连接请求。
     *   not authorized：客户端访问的实例权限校验失败导致TCP连接断开。
     *   clientId conflied：客户端标识冲突导致TCP连接断开。
     *   resource auth failed：客户端访问的Topic或Group ID资源权限校验失败导致TCP连接断开。
     *   no heart：客户端无心跳导致TCP连接断开。
     *   closed by client：客户端异常导致TCP连接断开。
     *   disconnected by client：客户端请求断开连接。
     *   invalid param：请求参数不合法导致TCP连接断开。
     *   Socket IOException：网络抖动或丢包导致TCP连接断开。
     * ChannelId 设备连接标识。
     * Time 设备动作发生的时间。
     * @throws Exception 异常
     */
    @ApiOperation(value = "分页查询微消息队列MQTT版客户端的设备轨迹")
    @RequestMapping(value = "/query",method = {RequestMethod.POST})
    public Result<Object> QueryMqttTraceDevice(@ApiParam(value = "返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之") @RequestParam(defaultValue = "false") Boolean Reverse ,
                                               @ApiParam(value = "需要查询轨迹信息的设备的Client ID",required = true) @RequestParam String ClientId,
                                               @ApiParam(value = "查询范围的起始时间戳",required = true) @RequestParam Long BeginTime,
                                               @ApiParam(value = "查询范围的终止时间戳",required = true) @RequestParam Long EndTime,
                                               @ApiParam(value = "当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空",required = true) @RequestParam Integer CurrentPage,
                                               @ApiParam(value = "分页查询，每页最多显示的消息数量，最小1条，最多100条",required = true) @RequestParam Integer PageSize) throws Exception {
        MqttConfigurer mqttConfigurer = new MqttConfigurer();
        com.aliyun.onsmqtt20200420.Client client = MqttClient.createClient(mqttConfigurer.getAccesskey(), mqttConfigurer.getSecretkey(), mqttConfigurer.getEndpoint());
        QueryMqttTraceDeviceRequest queryMqttTraceDeviceRequest = new QueryMqttTraceDeviceRequest()
                .setMqttRegionId(mqttConfigurer.getMqttregionid())
                .setInstanceId(mqttConfigurer.getInstanceid())
                .setReverse(Reverse)
                .setClientId(ClientId)
                .setBeginTime(BeginTime)
                .setEndTime(EndTime)
                .setCurrentPage(CurrentPage)
                .setPageSize(PageSize);
        try {
            QueryMqttTraceDeviceResponse response = client.queryMqttTraceDevice(queryMqttTraceDeviceRequest);
            JSONObject json = new JSONObject(response.toMap());
            String data = String.valueOf(json.getJSONObject("body"));
            return ResultGenerator.genSuccessResult(data);
        }catch (Exception exception){
            return ResultGenerator.genFailResult(exception.getMessage());
        }
    }

    /**
     * 调用QueryMqttTraceMessageOfClient查询指定设备的消息收发列表
     *
     * @param Reverse 返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之
     * @param ClientId 需要查询轨迹信息的设备的Client ID
     * @param BeginTime 查询范围的起始时间戳
     * @param EndTime 查询范围的终止时间戳
     * @param CurrentPage 当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空
     * @param PageSize 分页查询，每页最多显示的消息数量，最小1条，最多100条
     * @return RequestId 公共参数 Total 消息总数 CurrentPage 当前页 PageSize 每页消息数量 MessageOfClientList 返回的消息列表
     * Action 设备动作。取值说明如下：
     *   connect：客户端请求与服务端连接。
     *   close：TCP连接断开。
     *   disconnect：客户端请求与服务端断开连接。
     * ActionCode 设备动作的返回码。取值说明如下：
     *   mqtt.trace.action.connect：设备动作为connect时返回该参数值。
     *   mqtt.trace.action.close：设备动作为close时返回该参数值。
     *   mqtt.trace.action.disconnect：设备动作为disconnect时返回该参数值。
     * ActionInfo 设备动作的描述信息。取值说明如下：
     *   accept：服务端接收客户端发起的连接请求。
     *   not authorized：客户端访问的实例权限校验失败导致TCP连接断开。
     *   clientId conflied：客户端标识冲突导致TCP连接断开。
     *   resource auth failed：客户端访问的Topic或Group ID资源权限校验失败导致TCP连接断开。
     *   no heart：客户端无心跳导致TCP连接断开。
     *   closed by client：客户端异常导致TCP连接断开。
     *   disconnected by client：客户端请求断开连接。
     *   invalid param：请求参数不合法导致TCP连接断开。
     *   Socket IOException：网络抖动或丢包导致TCP连接断开。
     * ClientId 设备的Client ID。
     * MsgId 消息ID，即Message ID。
     * Time 消息发送的时间或被消费的时间。
     * @throws Exception 异常
     */
    @ApiOperation(value = "查询指定设备的消息收发列表")
    @RequestMapping(value = "/queryclient",method = {RequestMethod.POST})
    public Result<Object> QueryMqttTraceMessageOfClient(@ApiParam(value = "返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之") @RequestParam(defaultValue = "false") Boolean Reverse ,
                                               @ApiParam(value = "需要查询轨迹信息的设备的Client ID",required = true) @RequestParam String ClientId,
                                               @ApiParam(value = "查询范围的起始时间戳",required = true) @RequestParam Long BeginTime,
                                               @ApiParam(value = "查询范围的终止时间戳",required = true) @RequestParam Long EndTime,
                                               @ApiParam(value = "当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空",required = true) @RequestParam Integer CurrentPage,
                                               @ApiParam(value = "分页查询，每页最多显示的消息数量，最小1条，最多100条",required = true) @RequestParam Integer PageSize) throws Exception {
        MqttConfigurer mqttConfigurer = new MqttConfigurer();
        com.aliyun.onsmqtt20200420.Client client = MqttClient.createClient(mqttConfigurer.getAccesskey(), mqttConfigurer.getSecretkey(), mqttConfigurer.getEndpoint());
        QueryMqttTraceMessageOfClientRequest queryMqttTraceMessageOfClientRequest = new QueryMqttTraceMessageOfClientRequest()
                .setMqttRegionId(mqttConfigurer.getMqttregionid())
                .setInstanceId(mqttConfigurer.getInstanceid())
                .setReverse(Reverse)
                .setClientId(ClientId)
                .setBeginTime(BeginTime)
                .setEndTime(EndTime)
                .setCurrentPage(CurrentPage)
                .setPageSize(PageSize);
        try {
            QueryMqttTraceMessageOfClientResponse response = client.queryMqttTraceMessageOfClient(queryMqttTraceMessageOfClientRequest);
            JSONObject json = new JSONObject(response.toMap());
            String data = String.valueOf(json.getJSONObject("body"));
            return ResultGenerator.genSuccessResult(data);
        }catch (Exception exception){
            return ResultGenerator.genFailResult(exception.getMessage());
        }
    }

    /**
     * 调用QueryMqttTraceMessagePublish查询指定消息的发送轨迹
     *
     * @param MsgId 消息ID，即Message ID
     * @param BeginTime 查询范围的起始时间戳。单位：毫秒
     * @param EndTime 查询范围的终止时间戳。单位：毫秒
     * @return RequestId 公共参数 MessageTraceLists 返回的消息发送轨迹列表
     * Action 设备动作。取值说明如下：
     *   connect：客户端请求与服务端连接。
     *   close：TCP连接断开。
     *   disconnect：客户端请求与服务端断开连接。
     * ActionCode 设备动作的返回码。取值说明如下：
     *   mqtt.trace.action.connect：设备动作为connect时返回该参数值。
     *   mqtt.trace.action.close：设备动作为close时返回该参数值。
     *   mqtt.trace.action.disconnect：设备动作为disconnect时返回该参数值。
     * ActionInfo 设备动作的描述信息。取值说明如下：
     *   accept：服务端接收客户端发起的连接请求。
     *   not authorized：客户端访问的实例权限校验失败导致TCP连接断开。
     *   clientId conflied：客户端标识冲突导致TCP连接断开。
     *   resource auth failed：客户端访问的Topic或Group ID资源权限校验失败导致TCP连接断开。
     *   no heart：客户端无心跳导致TCP连接断开。
     *   closed by client：客户端异常导致TCP连接断开。
     *   disconnected by client：客户端请求断开连接。
     *   invalid param：请求参数不合法导致TCP连接断开。
     *   Socket IOException：网络抖动或丢包导致TCP连接断开。
     * ClientId 设备的Client ID。
     * MsgId 消息ID，即Message ID。
     * Time 消息发送的时间或被消费的时间。
     * @throws Exception 异常
     */
    @ApiOperation(value = "查询指定消息的发送轨迹")
    @RequestMapping(value = "/queryclientpublish",method = {RequestMethod.POST})
    public Result<Object> QueryMqttTraceMessagePublish(@ApiParam(value = "消息ID，即Message ID",required = true) @RequestParam String MsgId,
                                                        @ApiParam(value = "查询范围的起始时间戳",required = true) @RequestParam Long BeginTime,
                                                        @ApiParam(value = "查询范围的终止时间戳",required = true) @RequestParam Long EndTime) throws Exception {
        MqttConfigurer mqttConfigurer = new MqttConfigurer();
        com.aliyun.onsmqtt20200420.Client client = MqttClient.createClient(mqttConfigurer.getAccesskey(), mqttConfigurer.getSecretkey(), mqttConfigurer.getEndpoint());
        QueryMqttTraceMessagePublishRequest queryMqttTraceMessagePublishRequest = new QueryMqttTraceMessagePublishRequest()
                .setMqttRegionId(mqttConfigurer.getMqttregionid())
                .setInstanceId(mqttConfigurer.getInstanceid())
                .setMsgId(MsgId)
                .setBeginTime(BeginTime)
                .setEndTime(EndTime);
        try {
            QueryMqttTraceMessagePublishResponse response = client.queryMqttTraceMessagePublish(queryMqttTraceMessagePublishRequest);
            JSONObject json = new JSONObject(response.toMap());
            String data = String.valueOf(json.getJSONObject("body"));
            return ResultGenerator.genSuccessResult(data);
        }catch (Exception exception){
            return ResultGenerator.genFailResult(exception.getMessage());
        }
    }

    /**
     * 调用QueryMqttTraceMessageSubscribe查询指定消息的投递轨迹
     *
     * @param MsgId 消息ID，即Message ID
     * @param Reverse 返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之
     * @param ClientId 需要查询轨迹信息的设备的Client ID
     * @param BeginTime 查询范围的起始时间戳
     * @param EndTime 查询范围的终止时间戳
     * @param CurrentPage 当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空
     * @param PageSize 分页查询，每页最多显示的消息数量，最小1条，最多100条
     * @return RequestId 公共参数 Total 消息总数 CurrentPage 当前页 PageSize 每页消息数量 MessageTraceLists 返回的消息列表
     * Action 设备动作。取值说明如下：
     *   connect：客户端请求与服务端连接。
     *   close：TCP连接断开。
     *   disconnect：客户端请求与服务端断开连接。
     * ActionCode 设备动作的返回码。取值说明如下：
     *   mqtt.trace.action.connect：设备动作为connect时返回该参数值。
     *   mqtt.trace.action.close：设备动作为close时返回该参数值。
     *   mqtt.trace.action.disconnect：设备动作为disconnect时返回该参数值。
     * ActionInfo 设备动作的描述信息。取值说明如下：
     *   accept：服务端接收客户端发起的连接请求。
     *   not authorized：客户端访问的实例权限校验失败导致TCP连接断开。
     *   clientId conflied：客户端标识冲突导致TCP连接断开。
     *   resource auth failed：客户端访问的Topic或Group ID资源权限校验失败导致TCP连接断开。
     *   no heart：客户端无心跳导致TCP连接断开。
     *   closed by client：客户端异常导致TCP连接断开。
     *   disconnected by client：客户端请求断开连接。
     *   invalid param：请求参数不合法导致TCP连接断开。
     *   Socket IOException：网络抖动或丢包导致TCP连接断开。
     * ClientId 设备的Client ID。
     * MsgId 消息ID，即Message ID。
     * Time 消息发送的时间或被消费的时间。
     * @throws Exception 异常
     */
    @ApiOperation(value = "查询指定消息的投递轨迹")
    @RequestMapping(value = "/queryclientsubscribe",method = {RequestMethod.POST})
    public Result<Object> QueryMqttTraceMessageSubscribe(@ApiParam(value = "返回结果是否倒序显示。 true：按照设备活动时间倒序显示，最后一次的设备活动信息显示在第一条 false：反之") @RequestParam(defaultValue = "false") Boolean Reverse ,
                                                         @ApiParam(value = "需要查询轨迹信息的设备的Client ID",required = true) @RequestParam String ClientId,
                                                         @ApiParam(value = "消息ID，即Message ID",required = true) @RequestParam String MsgId,
                                                         @ApiParam(value = "查询范围的起始时间戳",required = true) @RequestParam Long BeginTime,
                                                         @ApiParam(value = "查询范围的终止时间戳",required = true) @RequestParam Long EndTime,
                                                         @ApiParam(value = "当前取第几页消息，从1开始递增。若输入参数大于总页数，则返回结果为空",required = true) @RequestParam Integer CurrentPage,
                                                         @ApiParam(value = "分页查询，每页最多显示的消息数量，最小1条，最多100条",required = true) @RequestParam Integer PageSize) throws Exception {
        MqttConfigurer mqttConfigurer = new MqttConfigurer();
        com.aliyun.onsmqtt20200420.Client client = MqttClient.createClient(mqttConfigurer.getAccesskey(), mqttConfigurer.getSecretkey(), mqttConfigurer.getEndpoint());
        QueryMqttTraceMessageSubscribeRequest queryMqttTraceMessageSubscribeRequest = new QueryMqttTraceMessageSubscribeRequest()
                .setMqttRegionId(mqttConfigurer.getMqttregionid())
                .setInstanceId(mqttConfigurer.getInstanceid())
                .setReverse(Reverse)
                .setClientId(ClientId)
                .setBeginTime(BeginTime)
                .setEndTime(EndTime)
                .setMsgId(MsgId)
                .setCurrentPage(CurrentPage)
                .setPageSize(PageSize);
        try {
            QueryMqttTraceMessageSubscribeResponse response = client.queryMqttTraceMessageSubscribe(queryMqttTraceMessageSubscribeRequest);
            JSONObject json = new JSONObject(response.toMap());
            String data = String.valueOf(json.getJSONObject("body"));
            return ResultGenerator.genSuccessResult(data);
        }catch (Exception exception){
            return ResultGenerator.genFailResult(exception.getMessage());
        }
    }
}
